/*
*	Copyright(c) 2020 lutianming email：641471957@qq.com
*
*	Sheeps may be copied only under the terms of the GNU Affero General Public License v3.0
*/

#ifndef _SERVER_PROTOCOL_H_
#define _SERVER_PROTOCOL_H_
#include "SheepsStruct.h"
#include "SheepsFactory.h"
#include <list>
#include <mutex>
#include <map>
#include "cJSON.h"

#define DefaultOneTaskUserCount 65000

extern int slogid;
extern bool proxy_open;
extern bool proxy_hook;

extern const char* ca_crt;
extern const char* user_crt;
extern const char* pri_key;

enum {
	HTTP_PROXY = 0,
	HTTPS_PROXY,
	CORS_PROXY
};

enum{
	PEER_UNNOWN = 0,
	PEER_UNDEFINE,
	PEER_SOCKS5_PROXY,
	PEER_STRESS,
	PEER_HTTP,
	PEER_HTTP_PROXY
};

enum{
	PROXY_INIT = 0,
	PROXY_AUTHED,
	PROXY_CONNECTING,
	PROXY_CONNECTED
};

enum{
	AGENT_DEFAULT = 0,
	AGENT_AUTH,
	AGENT_READY,
	AGENT_FAIL
};

typedef struct {
	char	ip[40];
	int		port;
	short	cpu;
	int		mem_total;
	int		adapter;
	volatile int	cpu_cast;
	volatile int	mem_cast;
	volatile int	adapter_cast;
	int		ready;
	uint8_t	projectid;
	char	groupid[32];
}t_sheeps_agent, * h_SHEEPS_AGENT;

typedef struct {
	int count;
	std::map<HSOCKET, t_sheeps_agent*>* agents;
}t_agent_group;

typedef struct {
	std::string name;
	std::string parms;
	std::map<std::string, t_agent_group*> groups;
	//std::map<int, int> groupids;
}t_project_config;

typedef struct {
	char	serverip[40];
	int		serverport;
	uint8_t proxytype;

	char	clientip[40];
	int		clientport;
	char	tempmsg[16];

	HSOCKET udpClientSock;
	HSOCKET proxySock;
	bool	ssl_conn;
	char	proxyStat;
	char	retry;
	unsigned long long sessionid;
}t_socks5_proxy, * h_SOCKS5_PROXY;

typedef struct {
	HSOCKET proxySock;
	unsigned long long sessionid;
	char	protocol;
	char	proxy_type;
	bool	ssl_conn;
	char	proxyStat;
	char*	data;
	int		len;
	int		port;
	char	host[40];
}t_http_proxy, *h_HTTP_PROXY;

#define T_HTTP_PROXY_SIZE sizeof(t_http_proxy)

class ServerProtocol :
	public BaseWorker
{
public:
	HSOCKET initSock = NULL;
	int peerType = PEER_UNNOWN;
	
	h_HTTP_PROXY	http_proxy = NULL;	//http or https proxy
	h_SOCKS5_PROXY	socks5_proxy = NULL;//proxy
	h_SHEEPS_AGENT	stressInfo = NULL;	//stress

public:
	ServerProtocol();
	~ServerProtocol();

public:
	void ConnectionMade(HSOCKET hsock, PROTOCOL protocol);
	void ConnectionFailed(HSOCKET hsock, int err);
	void ConnectionClosed(HSOCKET hsock, int err);
	void ConnectionRecved(HSOCKET hsock, const char* data, int len);

	int  CheckRequest(HSOCKET hsock, const char* data, int len);
};

extern int	AgentTotalCount;
extern std::vector<t_project_config*> ProjectConfig;
extern std::map<ServerProtocol*, std::string>* ProxyAddr;

bool ServerInit(char* configfile);

#endif // !_SERVER_PROTOCOL_H_